
/******************************************************************************
 * MODULE     : smoothen.cpp
 * DESCRIPTION: Smoothening handwritten curves
 * COPYRIGHT  : (C) 2016  Joris van der Hoeven
 *******************************************************************************
 * This software falls under the GNU general public license version 3 or later.
 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
 ******************************************************************************/

#include "point.hpp"

/******************************************************************************
 * Remove superfluous points
 ******************************************************************************/

static void
extract (array<point>& r, array<point> a, array<int> prev, int i) {
  if (prev[i] != -1) extract (r, a, prev, prev[i]);
  r << a[i];
}

array<point>
simplify (array<point> a, double eps, double thr) {
  if (N (a) <= 2) return a;
  array<int>    prev_i;
  array<double> prev_d;
  prev_i << -1;
  prev_d << 0.0;
  int count= 0;
  for (int i= 1; i < N (a); i++) {
    prev_i << -1;
    prev_d << 1.0e100;
    for (int j= i - 1; j >= 0; j--) {
      count++;
      if (norm (a[i] - a[j]) > thr) break;
      else if (norm (a[i] - a[j]) < eps) continue;
      else if (prev_d[j] >= prev_d[i]) continue;
      else {
        double s= 0.0;
        for (int k= j + 1; k < i; k++)
          s+= seg_dist (a[i], a[j], a[k]);
        if (prev_d[j] + s < prev_d[i]) {
          prev_i[i]= j;
          prev_d[i]= prev_d[j] + s;
        }
      }
    }
  }
  if (prev_i[N (a) - 1] == -1) return a;
  array<point> r;
  extract (r, a, prev_i, N (a) - 1);
  // cout << count << "\n";
  return r;
}
